package com.zeratul.common.event.base;

import cn.hutool.core.util.ObjectUtil;
import com.zeratul.common.core.exception.ServiceException;
import com.zeratul.common.core.utils.spring.SpringUtils;
import com.zeratul.common.event.base.callback.BaseSendCallback;
import com.zeratul.common.event.base.serial.BaseEventSerialization;
import com.zeratul.common.event.codes.EventResultCodes;
import com.zeratul.common.event.domain.ZtEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * 发布者-处理层接口
 */
public interface BasePublishHandler {

    Logger log = LoggerFactory.getLogger(BasePublishHandler.class);

    /**
     * 序列化事件对象
     */
    default <T> byte[] serialize(ZtEvent<T> ztEvent) {
        BaseEventSerialization serialization = SpringUtils.getBean(BaseEventSerialization.class);
        if (ObjectUtil.isNull(serialization)) {
            throw new ServiceException(EventResultCodes.NOT_FOUND_SERIALIZER);
        }
        return serialization.serialize(ztEvent);
    }

    /**
     * 执行结果的回调
     */
    default <T> void sendCallback(ZtEvent<T> ztEvent, Throwable t) {
        //获取全局回调对象
        Map<String, BaseSendCallback> callbackMaps = SpringUtils.getBeansOfType(BaseSendCallback.class);
        if (ObjectUtil.isEmpty(callbackMaps)) {
            return;
        }
        //执行回调
        for (BaseSendCallback callback : callbackMaps.values()) {
            try {
                //判断是否执行
                if (!callback.isSupport(ztEvent, t)) {
                    continue;
                }

                //执行回调
                boolean flag = callback.sendCallback(ztEvent, t);
                if (!flag) {
                    break;
                }
            } catch (Exception e) {
                log.error("【事件总线】【发布者】事件发送回调报错！事件：{}", ztEvent, e);
            }
        }
    }


    /**
     * 执行事件发送
     * @param ztEvent - 事件对象
     * @param eventBytes - 事件对象序列化后的字节数组
     * @param <T>
     */
    <T> void doSendEvent(ZtEvent<T> ztEvent, byte[] eventBytes);
}
